import java.io.IOException;
import java.io.InputStream;


public abstract class BytesReader {

	InputStream in;
	public BytesReader(InputStream in) {
		this.in = in;
	}
	
	public static BytesReader newBytesReader(InputStream in, boolean bigEndian) {
		if (bigEndian) {
			return new BEBytesReader(in);
		} else {
			return new LEBytesReader(in);
		}
	}
	
	abstract byte readByte() throws IOException;
	abstract short readShort() throws IOException;
	abstract int readInt() throws IOException;
}

class LEBytesReader extends BytesReader {
	
	public LEBytesReader(InputStream in) {
		super(in);
	}

	byte readByte() throws IOException {
		return (byte) (in.read() & 0xFF);
	}
	
	short readShort() throws IOException {
		int b1 = in.read();
		int b2 = in.read();
		return (short) ((b2 << 8) + b1); 
	}
	
	int readInt() throws IOException {
		int b1 = in.read();
		int b2 = in.read();
		int b3 = in.read();
		int b4 = in.read();
		return (b4 << 24) + (b3 << 16) + (b2 << 8) + b1; 
	}
}

class BEBytesReader extends BytesReader {
	
	public BEBytesReader(InputStream in) {
		super(in);
	}

	byte readByte() throws IOException {
		return (byte) (in.read() & 0xFF);
	}
	
	short readShort() throws IOException {
		int b1 = in.read();
		int b2 = in.read();
		return (short) ((b1 << 8) + b2); 
	}
	
	int readInt() throws IOException {
		int b1 = in.read();
		int b2 = in.read();
		int b3 = in.read();
		int b4 = in.read();
		return (b1 << 24) + (b2 << 16) + (b3 << 8) + b4; 
	}
}